import * as iconv from 'iconv-lite';
import { GtsFpnDataReader } from '@/lib/GtsFpnDataReader';
import { Flac3dExporter } from '@/lib/Flac3d/Flac3dExporter';
import { Flac3dFileContent } from '@/lib/Flac3d/Flac3dData';
import { WorkerMessageType, WorkerMessage } from '@/lib/WorkerMessage';
import { AbaqusExporter } from '@/lib/Abaqus/AbaqusExporter';
import { AbaqusFileContent } from '@/lib/Abaqus/AbaqusData';

//
// Context of web worker
//
const ctx: Worker = self as any;

ctx.onmessage = event => {
    function reportProgress(workerContext: any, progress: number): void {
        workerContext.postMessage({
            messageType: WorkerMessageType.Progressing,
            messageData: progress
        });
    }

    function reportError(workerContext: any, errorDescription: string): void {
        workerContext.postMessage({
            messageType: WorkerMessageType.ErrorOccured,
            messageData: errorDescription
        });
    }

    function reportResult(
        workerContext: any,
        result: Flac3dFileContent | AbaqusFileContent
    ): void {
        workerContext.postMessage({
            messageType: WorkerMessageType.Completed,
            messageData: result
        });
    }

    console.log('Worker: receiving fileData ...');
    reportProgress(ctx, 0);

    const msg = event.data as WorkerMessage;
    const fileData = msg.messageData as string;
    const textContent = iconv.decode(Buffer.from(fileData, 'utf-8'), 'gbk');
    const allInputLines = textContent.split('\r\n');

    reportProgress(ctx, 20);

    console.log('Worker: Parsing data ...');
    const gtsReader = new GtsFpnDataReader();
    const femMesh = gtsReader.ParseFpnData(allInputLines);
    if (!femMesh) {
        console.log('Worker: *** Parsing data failed! ***');
        reportError(ctx, '*** Parsing data failed! ***');
        return;
    }

    reportProgress(ctx, 50);

    if (msg.messageType === WorkerMessageType.ExportFlac3d) {
        console.log('Worker: Converting data ...');
        const exporter = new Flac3dExporter();
        const flac3dFileContent = exporter.DoExport(femMesh);

        reportProgress(ctx, 90);

        console.log('Worker: send result to parent ...');
        reportResult(ctx, flac3dFileContent);
    } else if (msg.messageType === WorkerMessageType.ExportAbaqus) {
        console.log('Worker: Converting data ...');
        const exporter = new AbaqusExporter();
        const abaqusFileContent = exporter.DoExport(femMesh);

        reportProgress(ctx, 90);

        console.log('Worker: send result to parent ...');
        reportResult(ctx, abaqusFileContent);
    }
};
